SDUT OJ 2054 双向链表的实现 (结构体node指针+遍历 *【模板】)

双向链表

 

Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^

题目描述

学会了单向链表,我们又多了一种解决问题的能力,单链表利用一个指针就能在内存中找到下一个位置,这是一个不会轻易断裂的链。但单链表有一个弱点——不能回指。比如在链表中有两个节点A,B,他们的关系是B是A的后继,A指向了B,便能轻易经A找到B,但从B却不能找到A。一个简单的想法便能轻易解决这个问题——建立双向链表。在双向链表中,A有一个指针指向了节点B,同时,B又有一个指向A的指针。这样不仅能从链表头节点的位置遍历整个链表所有节点,也能从链表尾节点开始遍历所有节点。对于给定的一列数据,按照给定的顺序建立双向链表,按照关键字找到相应节点,输出此节点的前驱节点关键字及后继节点关键字。

输入

第一行两个正整数n(代表节点个数),m(代表要找的关键字的个数)。接下来n行每行有一个整数为关键字key(数据保证关键字在数列中没有重复)。接下来有m个关键字,每个占一行。

输出

对给定的每个关键字,输出此关键字前驱节点关键字和后继节点关键字。如果给定的关键字没有前驱或者后继,则不输出。给定关键字为每个输出占一行。

 

示例输入

10 3
1 2 3 4 5 6 7 8 9 0
3
5
0

示例输出

2 4
4 6
9

提示

 代码:
//双向链表的基本操作:建表,删除,插入  
  
#include <stdio.h>  
#include <string.h>  
#include <stdlib.h>  
#include <algorithm>  
  
using namespace std;  
  
  
struct node  
{  
    int date;  
    struct node *next;  
    struct node *pre;  
};  
  
  
//双向链表的建表(顺序创建具有n个节点的双向链表)  
  
struct node *Creat_list(int n)  
{  
    int i;  
    struct node *head, *tail, *p;  
    head = new struct node;  
    head->next=NULL;  
    head->pre=NULL;  //架空head  
    tail=head;  
  
    for(i=0; i<n; i++)  
    {  
        p=new struct node;  
        scanf("%d", & p->date );  
        p->next=NULL;  
        p->pre=NULL;  
                     //一个带有数据的节点创建成功  
        tail->next=p;  
        p->pre=tail;  
        tail=p;  
    }  
    return head;  
}  
  
  
int main()  
{  
    struct node *head, *p;  
    int n, m;  
    scanf("%d %d", &n, &m);  
  
    head = Creat_list(n);  
    int i, dd;  
  
    for(i=0; i<m; i++)  
    {  
        scanf("%d", &dd);  
        p=head->next;  
        while(p)  
        {  
            if(p->date == dd)  
            {  
                break;  
            }  
            p=p->next;  
        }  
        int flag=0;  
        if(p->pre!=head)  
        {  
            printf("%d", p->pre->date );  
            flag=1;  
        }  
        if(p->next)  
        {  
            if(flag==1)  
            printf(" %d", p->next->date );  
            else  
            printf("%d", p->next->date );  
        }  
        printf("\n");  
    }  
    return 0;  
}  
  
/* 
 
双向链表的模板!!! 
//双向链表的基本操作:建表,删除,插入 
 
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <algorithm> 
 
using namespace std; 
 
 
struct node 
{ 
    int date; 
    struct node *next; 
    struct node *pre; 
}; 
 
 
//双向链表的建表(顺序创建具有n个节点的双向链表) 
 
struct node *Creat_list(int n) 
{ 
    int i; 
    struct node *head, *tail, *p; 
    head = new struct node; 
    head->next=NULL; 
    head->pre=NULL;  //架空head 
    tail=head; 
 
    for(i=0; i<n; i++) 
    { 
        p=new struct node; 
        scanf("%d", & p->date ); 
        p->next=NULL; 
        p->pre=NULL; 
                     //一个带有数据的节点创建成功 
        tail->next=p; 
        p->pre=tail; 
        tail=p; 
    } 
    return head; 
} 
 
 
 
//双向链表中 删除数据值为key的所指节点元素 
 
struct node *Delete(struct node *head, int key) 
{ 
    struct node *p; 
    p=head->next; 
    while( p  ) 
    { 
        if(p->date == key ) 
        { 
            p->pre->next=p->next; 
            if(p->next) 
            { 
                p->next->pre=p->pre;   
            } 
            //break; 
        } 
        p=p->next; //注意对应的那 
    } 
 
    return head; 
} 
 
//在该双向链表的 第pos个位置之后 插入 值为key的节点元素 (在首(第一个元素的位置)和尾(最后一个元素)插入容易出现bug, 所以需要注意) 
struct node *Insert(struct node *head, int pos, int key )  
{ 
    struct node *p; 
    p=head->next; 
 
    struct node *q; 
    q=new struct node; 
    q->date=key;  q->next=NULL;  q->pre=NULL;  //创建要插入的节点 
 
    int cnt=0; //计数变量 
 
    if(pos==0) //特殊情况,如果我们想在最前面进行插入 
    { 
        if(head->next) 
        { 
            head->next->pre=q;  q->next=head->next; 
            head->next=q;       q->pre=head; 
        } 
        else 
        { 
            head->next=q;  q->pre=head; 
        } 
    } 
    else 
    { 
        while(p) 
        { 
            cnt++; 
            if(cnt==pos) 
            { 
                break; 
            } 
            p=p->next; 
        } 
        if(p->next) 
        { 
            p->next->pre=q; q->next=p->next; 
            p->next=q;  q->pre=p; 
        } 
        else 
        { 
            p->next=q;  q->pre=p; 
        } 
    } 
    return head; 
} 
 
 
int main() 
{ 
    struct node *head, *p; 
    int n; 
    scanf("%d", &n); 
    head = Creat_list(n); //创建双向链表 
    p=head->next; 
    while(p) 
    { 
        printf("%d\t", p->date ); 
        p=p->next; 
    } 
    printf("\n\n"); 
 
 
 
    struct node *head2; //存储删除某个元素后的链表 
    int key; 
    scanf("%d", &key ); //读入要删除的特定元素 
 
    head2 = Delete(head, key); //执行 链表删除函数 
    p=head2->next; 
    while(p) 
    { 
        printf("%d\t", p->date ); 
        p=p->next; 
    } 
    printf("\n\n"); 
 
 
    struct node *head3; 
    int pos; 
    scanf("%d %d", &pos, &key ); 
    head3 = Insert(head2, pos, key );  
 
    p=head3->next;  //输出最后状态的链表  
    while(p) 
    { 
        printf("%d\t", p->date ); 
        p=p->next; 
    } 
    printf("\n"); 
 
    return 0; 
} 
 
*/   
  

 

posted @ 2015-01-18 12:24  我喜欢旅行  阅读(576)  评论(0编辑  收藏  举报